<?php
class ModelToolSeoPackage extends Model {

    public function hrefLang($linkRoute = false, $linkUrl = '') {
        if (!$this->config->get('mlseo_hreflang')) {
            return;
        }

        $this->load->model('localisation/language');
        $langs = $this->model_localisation_language->getLanguages();

        // save current language values
        $current_config_lang = $this->config->get('config_language') ? $this->config->get('config_language') : 'en-gb';
        if (isset($langs[$current_config_lang])) {
            $langs = [
                $current_config_lang => $langs[$current_config_lang]
            ];
        } else {
            $langs = [];
        }

        $current_lang_id = $this->config->get('config_language_id');
        $current_lang_code = isset($this->session->data['language']) ? $this->session->data['language'] : '';

        if (!$linkRoute) {
            // construct url
            $data = $this->request->get;

            // do not display hreflang if page or limit parameter
            if (!empty($data['route']) && $data['route'] == 'product/category' && count($data) !== 3) {
                //return; // disabled, seems now necessary by google
            }

            unset($data['_route_']);
            unset($data['site_language']);
            unset(/*$data['page'],*/ $data['limit'], $data['order'], $data['sort']);

            if (isset($data['route']) && $data['route']) {
                $route = $data['route'];
            } else {
                $route = 'common/home';
            }

            unset($data['route']);

            $url = '';

            if (isset($data['path'])) {
                $url .= 'path=' . $data['path'] . '&';
                unset($data['path']);
            }

            if (isset($data['language'])) {
                unset($data['language']);
            }

            if ($data) {
                $data = array_reverse($data);
                $url .=  urldecode(http_build_query($data, '', '&'));
            }
        } else {
            $route = $linkRoute;
            $url = $linkUrl;
        }

        // not possible to get correct data so do not include hreflang for journal
        if (isset($route) && in_array($route, array('journal3/blog', 'journal3/blog/category', 'journal3/blog/post'))) {
            return;
        }

        $hreflangs = array();

        // handle sub-stores rewriting
        if ($this->config->get('mlseo_store_mode')) {
            $lang_to_store = $this->config->get('mlseo_lang_to_store');
        }

        // generate hreflangs
        foreach ($langs as $lang) {
            // set language to get each link
            $this->config->set('config_language', $lang['code']);
            $this->config->set('config_language_id', $lang['language_id']);
            $this->session->data['language'] = $lang['code'];

            $addLanguage = '';

            if (version_compare(VERSION, '4', '>=')) {
                $addLanguage = $url ? '&language='.$lang['code'] : 'language='.$lang['code'];
            }

            if (!empty($lang_to_store[$lang['code']])) {
                $hreflangs[] = array(
                    'href' => !empty($lang_to_store) ? str_replace(array(rtrim($this->config->get('config_url'),'/'), rtrim($this->config->get('config_ssl'),'/')), array_map(array('self','trimSlash'), $lang_to_store[$lang['code']]), $this->url->link($route, $url.$addLanguage)) : $this->url->link($route, $url.$addLanguage),
                    'hreflang' => (!$this->config->get('mlseo_hreflang_mode') ? substr($lang['code'], 0, 2) : $lang['code'])
                );

                if ($this->config->get('mlseo_hreflang_xdefault')) {
                    if ($this->config->get('mlseo_default_lang') == $lang['code']) {
                        $hreflangs[] = array(
                            'href' => !empty($lang_to_store) ? str_replace(array(rtrim($this->config->get('config_url'),'/'), rtrim($this->config->get('config_ssl'),'/')), array_map(array('self','trimSlash'), $lang_to_store[$lang['code']]), $this->url->link($route, $url.$addLanguage)) : $this->url->link($route, $url.$addLanguage),
                            'hreflang' => 'x-default'
                        );
                    }
                }
            } else {
                $hreflangs[] = array(
                    'href' => $this->url->link($route, $url.$addLanguage),
                    'hreflang' => (!$this->config->get('mlseo_hreflang_mode') ? substr($lang['code'], 0, 2) : $lang['code'])
                );

                if ($this->config->get('mlseo_hreflang_xdefault')) {
                    if ($this->config->get('mlseo_default_lang') == $lang['code']) {
                        $hreflangs[] = array(
                            'href' => $this->url->link($route, $url.$addLanguage),
                            'hreflang' => 'x-default'
                        );
                    }
                }
            }
        }

        if (!$this->config->get('mlseo_hreflang_xdefault')) {
            if (!empty($lang_to_store) && $route == 'common/home') {
                $hreflangs[] = array(
                    'href' => $this->config->get('config_url'),
                    'hreflang' => 'x-default'
                );
            }
        }

        // restore current language values
        $this->config->set('config_language', $current_config_lang);
        $this->config->set('config_language_id', $current_lang_id);
        $this->session->data['language'] = $current_lang_code;

        if ($linkRoute) {
            return $hreflangs;
        }
        $output =  '';

        foreach ($hreflangs as $link) {
            $output .=  '<link rel="alternate" href="'.$link['href'].'" hreflang="'.$link['hreflang'].'"/>'."\n";
        }

        $this->document->addSeoMeta($output);
    }

    private static function trimSlash($val) {
        return rtrim($val, '/');
    }

    public function metaRobots() {
//        if (!$this->config->get('mlseo_robots')) {
//            return;
//        }
//
//        // do not display if already defined
//        if (strpos($this->document->renderSeoMeta(), '<meta name="robots"') !== false) {
//            return;
//        }
//
//        $page = !empty($this->request->get['route']) ? $this->request->get['route'] : 'common/home';
//        $page = str_replace(array('common/home', 'product/product', 'product/category', 'information/information', 'information/contact', 'product/search', 'product/manufacturer/info'),
//            array('home', 'product', 'category', 'information', 'contact', 'search', 'manufacturer'), $page);
//
//        if ($page == 'search' && !empty($this->request->get['tag'])) {
//            $page = 'tag';
//        }
//
//        if (strstr($page, '/', true)) {
//            $page = strstr($page, '/', true);
//        }
//
//        // set default robots value
//        $robots = $this->config->get('mlseo_meta_robots');
//        $value = isset($robots[$page]) ? $robots[$page] : '';
//        $getParams = $this->request->get;
//
//        if (isset($getParams['ignorenitro'])) {
//            unset($getParams['ignorenitro']);
//        }
//
//        if ($page == 'error') {
//            $value = 'none';
//        } else if ($page == 'search') {
//            if (empty($this->request->get['tag']) || isset($this->request->get['page']) || isset($this->request->get['limit']) || isset($this->request->get['sort'])) {
//                $value = 'none';
//            }
//        } elseif (!empty($this->request->get['page']) && $this->request->get['page'] !== '1') {
//            $value = 'noindex';
//        } elseif (!empty($this->request->get['limit']) || !empty($this->request->get['sort'])) {
//            $value = 'noindex';
//        } elseif (($page == 'category' && count($getParams) > 3) || ($page == 'product' && count($getParams) > 4)) {
//            // no index if any extra parameter in category
//            $value = 'noindex';
//        }
//
//        if ($value == 'none' || $value == 'noindex') {
//            $sitemapConfig = $this->config->get('advanced_sitemap_cfg');
//
//            if (!empty($sitemapConfig['custom_links_include'])) {
//                $custom_links_include = explode("\n", $sitemapConfig['custom_links_include']);
//                foreach ($custom_links_include as $k => $v) {
//                    list($custType, $custUrl) = explode('@',$v, 2);
//
//                    if ("http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" == $custUrl) {
//                        $value = '';
//                    }
//                }
//            }
//        }
//
//        if (!$value) {
//            return;
//        }
//
//        $output = '<meta name="robots" content="'.$value.'"/>'."\n";
//
//        $this->document->addSeoMeta($output);
    }

    public function richSnippets() {
//        $page = !empty($this->request->get['route']) ? $this->request->get['route'] : 'common/home';
//        $page = str_replace(array('common/home', 'product/product', 'product/category', 'information/information', 'information/contact', 'extension/d_blog_module/post'),
//            array('home', 'product', 'category', 'information', 'contact', 'blogs'), $page);
//        $metas = '';
//
//        switch ($page) {
//            case 'home': $types = array('gpublisher', 'microdata', 'opengraph', 'tcard'); break;
//            case 'category': $types = array('opengraph'); break;
//            default: $types = array(); break;
//        }
//
//        foreach ($types as $type) {
//            if (!$this->config->get('mlseo_'.$type)) continue;
//            $metas .= $this->rich_snippet($type, $page);
//        }
//
//        $metas .= html_entity_decode($this->config->get('mlseo_fb_pixel'), ENT_QUOTES, 'UTF-8');
//
//        $this->document->addSeoMeta($metas);
    }

    public function rich_snippet($type, $page, $data = array()) {
//        $config = $data['config'] = $this->config->get('mlseo_'.$type.'_data');
//
//        if ($page == 'home' && $type == 'gpublisher') {
//            $data['url'] = $config['url'];
//        } else if ($page == 'product') {
//            // currency
//            if (isset($this->session->data['currency'])) {
//                $data['currency'] = $this->session->data['currency'];
//            } else {
//                $data['currency'] = $this->currency->getCode();
//            }
//
//            // get unformatted price
//            $data['price'] = $this->currency->format($this->tax->calculate($data['product_info']['price'], $data['product_info']['tax_class_id'], $this->config->get('config_tax')), $data['currency'], 0, false);
//
//            if ($data['special']) {
//                $data['special'] = $this->currency->format($this->tax->calculate($data['product_info']['special'], $data['product_info']['tax_class_id'], $this->config->get('config_tax')),$data['currency'], 0, false);
//            }
//
//            // category
//            $category = array();
//
//            foreach ($data['breadcrumbs'] as $breadcrumb) {
//                if (strip_tags($breadcrumb['text'])) {
//                    $category[] = strip_tags($breadcrumb['text']);
//                }
//            }
//
//            if (!empty($data['product_info']['product_id'])) {
//                $data['product_url'] = $this->url->link('product/product', 'product_id='.$data['product_info']['product_id'],true);
//            }
//
//            if ($type == 'opengraph') {
//                $data['thumb'] = $this->model_tool_image->resize($data['product_info']['image'], 1024, 1024);
//            }
//
//            $data['category'] = implode(' &raquo; ', $category);
//
//            $this->load->model('catalog/product');
//            $product_categorys = $this->model_catalog_product->getCategoriesName($data['product_id']);
//            if(!empty($product_categorys)){
//                $product_category_name = array_column($product_categorys,"name");
//                $data['category'] = implode(",", $product_category_name);
//            }
//
//            // reviews
//            $data['reviews'] = array();
//
//            if (!empty($config['reviews']) && in_array($type, array('microdata', 'opengraph')) && !empty($data['product_id'])) {
//                $this->load->model('catalog/review');
//                $data['reviews'] = $this->model_catalog_review->getReviewsByProductId($data['product_id']);
//            }
//
//            $data['microdata_desc'] = $this->config->get('mlseo_microdata_desc');
//        } else if ($page == 'home') {
//            $seo_meta = $this->config->get('mlseo_store');
//            if (isset($seo_meta[$this->config->get('config_store_id').$this->config->get('config_language_id')])) {
//                $seo_meta = $seo_meta[$this->config->get('config_store_id').$this->config->get('config_language_id')];
//            }
//
//            $data['url'] = $this->url->link('common/home');
//
//            $this->load->model('tool/image');
//
//            $logo = $this->config->get('config_logo');
//            $data['logo'] = '';
//
//
//            if (is_array($logo) && isset($logo[$this->config->get('config_language_id')]) && is_file(DIR_IMAGE . $logo[$this->config->get('config_language_id')])) {
//                // compatibility with multilingual logo extensions
//                $data['logo'] = $this->model_tool_image->resize($logo[$this->config->get('config_language_id')], 300, 300); // 300x300 for fb
//            } else if (is_string($logo) && is_file(DIR_IMAGE . $logo)) {
//                $data['logo'] = $this->model_tool_image->resize($logo, 300, 300); // 300x300 for fb
//            } else if ($this->config->get('config_image') && is_file(DIR_IMAGE . $this->config->get('config_image'))) {
//                $data['logo'] = $this->model_tool_image->resize($this->config->get('config_image'), 300, 300); // 300x300 for fb
//            }
//
//            if (!empty($seo_meta['seo_title'])) {
//                $data['title'] = $seo_meta['seo_title'];
//            } else if ($this->config->get('config_meta_title')) {
//                $data['title'] = $this->config->get('config_meta_title');
//            } else {
//                $data['title'] = $this->config->get('config_title');
//            }
//
//            if (!empty($seo_meta['description'])) {
//                $data['desc'] = $seo_meta['description'];
//            } else {
//                $data['desc'] = $this->config->get('config_meta_description');
//            }
//        } else if ($page == 'category' && !empty($this->request->get['path'])) {
//            $this->load->model('catalog/category');
//            $path = $this->request->get['path'];
//            $category_ids = explode('_', $path);
//            $category_id = end($category_ids);
//            $category_info = $this->model_catalog_category->getCategory($category_id);
//
//            if (!empty($category_info)) {
//                $data['title'] = $category_info['name'];
//                $this->load->model('tool/image');
//                $data['image'] = $this->model_tool_image->resize($category_info['image'], 300, 300);
//                if (!empty($category_info['meta_description'])) {
//                    $data['description'] = strip_tags(html_entity_decode($category_info['meta_description'], ENT_QUOTES, 'UTF-8'));
//                } else {
//                    $data['description'] = substr(strip_tags(html_entity_decode($category_info['description'], ENT_QUOTES, 'UTF-8')), 0, 300);
//                }
//                $data['url'] = $this->url->link('product/category','path='.$path, true);
//            } else {
//                $data['title'] = '';
//                $data['image'] = '';
//                $data['description'] = '';
//                $data['url'] = '';
//            }
//
//        } else if ($page == 'info') {
//            if (!empty($this->request->get['information_id'])) {
//                $information_id = (int)$this->request->get['information_id'];
//            } else {
//                $information_id = 0;
//            }
//
//            $data['url'] = $this->url->link('information/information', 'information_id='.$information_id);
//        }else if ($page == 'blogs') {
//            $post_data['author_name'] = 'LovelyPetPal';
//            $post_data['publisher_name'] = $post_data['publisher_logo'] = "LovelyPetPal store";
//            $post_data['articleSection'] = 'LovelyPetPal Blogs';
//        }
//
//        // display
//        $data['config_name'] = $this->config->get('config_name');
//        $data['type'] = $type;
//        $data['page'] = $page;
//
//        if ($type == 'microdata') {
//            return $this->microdataJson($page, $data);
//        }
//
//        if (version_compare(VERSION, '4', '>=')) {
//            $tpl = new \Opencart\System\Library\Template('template');
//            $tpl->addPath('extension/complete_seo', DIR_EXTENSION . 'complete_seo/catalog/view/template/');
//            return $tpl->render('extension/complete_seo/module/seopackage_rich_snippet', $data);
//        } else if (version_compare(VERSION, '3', '>=')) {
//            $template = new Template('template', $this->registry);
//            foreach ($data as $key => $value) {
//                $template->set($key, $value);
//            }
//
//            $rf = new ReflectionMethod('Template', 'render');
//
//            if ($rf->getNumberOfParameters() > 2) {
//                return $template->render('default/template/module/seopackage_rich_snippet', $this->registry, false);
//            } else {
//                return $template->render('default/template/module/seopackage_rich_snippet', false);
//            }
//
//            return $template->render('default/template/module/seopackage_rich_snippet');
//        } else if (version_compare(VERSION, '2.2', '>=')) {
//            $template = new Template(version_compare(VERSION, '2.3', '>=') ? 'php': 'basic');
//            foreach ($data as $key => $value) {
//                $template->set($key, $value);
//            }
//            return $template->render('default/template/module/seopackage_rich_snippet.tpl', null); // null is for compatibility with fastor theme
//        } elseif (method_exists($this->load, 'view')) {
//            return $this->load->view('default/template/module/seopackage_rich_snippet.tpl', $data);
//        } else {
//            $template = new Template();
//            $template->data = &$data;
//            return $template->fetch('default/template/module/seopackage_rich_snippet.tpl');
//        }
    }

    public function getSeoDescription($type, $item_id) {
        $store_id = $this->config->get('mlseo_multistore') ? $this->config->get('config_store_id') : 0;

        $seoTable = 'seo_';
        $whereStore = "AND store_id = '".(int) $store_id."'";

        if (!$store_id && $type != 'manufacturer') {
            $seoTable = '';
            $whereStore = '';
        }

        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . $seoTable.$type."_description d WHERE ".$this->db->escape($type)."_id = '" . (int)$item_id . "' AND language_id = '".(int) $this->config->get('config_language_id')."'".$whereStore)->row;

        if (!empty($query['description'])) {
            if (defined('HTTPS_SERVER')) {
                $query['description'] = str_replace(array(HTTP_SERVER, HTTPS_SERVER), array($this->config->get('config_url'), $this->config->get('config_ssl')), $query['description']);
            } else {
                $query['description'] = $query['description'];
            }
        }

        return $query;
    }

    public function microdataJson($page, $data) {
        $config = !empty($data['config']) ? $data['config'] : [];
        $output = '';

        if (empty($data['url'])) {
            if (!empty($this->request->server['HTTPS'])) {
                $data['url'] = $this->config->get('config_ssl');
            } else {
                $data['url'] = $this->config->get('config_url');
            }
        }

        if (empty($data['logo'])) {
            //$data['logo'] = $data['url'] . 'image/' . $this->config->get('config_logo');
            $this->load->model('tool/image');

            $logo = $this->config->get('config_logo');
            $data['logo'] = '';

            if (is_array($logo) && isset($logo[$this->config->get('config_language_id')]) && is_file(DIR_IMAGE . $logo[$this->config->get('config_language_id')])) {
                // compatibility with multilingual logo extensions
                $data['logo'] = $this->model_tool_image->resize($logo[$this->config->get('config_language_id')], 300, 300); // 300x300 for fb
            } else if (is_string($logo) && is_file(DIR_IMAGE . $logo)) {
                $data['logo'] = $this->model_tool_image->resize($logo, 300, 300); // 300x300 for fb
            } else if ($this->config->get('config_image') && is_file(DIR_IMAGE . $this->config->get('config_image'))) {
                $data['logo'] = $this->model_tool_image->resize($this->config->get('config_image'), 300, 300); // 300x300 for fb
            }
        }

        // Breadcrumbs
        if (in_array($page, array('product', 'category', 'manufacturer', 'information', 'contact')) && !empty($config['breadcrumbs'])) {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'BreadcrumbList';

            if (!empty($data['breadcrumbs'])) {
                $pos = 1;
                foreach ($data['breadcrumbs'] as $breadcrumb) {
                    $json['itemListElement'][] = array(
                        '@type' => 'ListItem',
                        'position' => $pos++,
                        'item' => array(
                            '@id' => urldecode($breadcrumb['href']),
                            'name' => strip_tags($breadcrumb['text']) ? html_entity_decode(strip_tags($breadcrumb['text']), ENT_QUOTES, 'UTF-8') : html_entity_decode($data['config_name'], ENT_QUOTES, 'UTF-8'),
                        ),
                    );
                }
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Category
        if ($page == 'category' && !empty($config['category'])) {
            if (isset($this->request->get['path']) && !empty($config['cat_reviews'])) {
                $parts = explode('_', (string)$this->request->get['path']);

                $category_id = (int)array_pop($parts);

                $filter_data = array(
                    'filter_category_id' => $category_id,
                );

                $product_total = $this->model_catalog_product->getTotalProducts($filter_data);

                $products = $this->model_catalog_product->getProducts($filter_data);

                $best_rating = $review_total = 0;

                foreach ($products as $product) {
                    $review_total += $product['rating'];
                    $best_rating = ($product['rating'] > $best_rating) ? $product['rating'] : $best_rating;
                }

                if ($product_total > 0 && $review_total > 0) {
                    $json = array();

                    $json['aggregateRating'] = array(
                        '@type' => 'AggregateRating',
                        'ratingValue' => round($review_total / $product_total, 1),
                        'bestRating' => $best_rating,
                        'reviewCount' => $product_total,
                    );

                    $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
                }
            }
        }

        // Product
        if ($page == 'product' && !empty($config['product'])) {
            $product_url = $this->url->link('product/product', 'product_id=' . $data['product_id'], true);
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'Product';
            $json['@id'] = $product_url;
            $json['url'] = $product_url;
            $json['name'] = !empty($data['product_info']['meta_title']) ? html_entity_decode($data['product_info']['meta_title'],
                ENT_QUOTES, 'UTF-8') : html_entity_decode($data['heading_title'], ENT_QUOTES, 'UTF-8');
            $json['image'] = $data['thumb'];

            $has_idtentifier = false;

            if (!empty($config['model'])) {
                $json['model'] = $data['model'];
            }

            if (!empty($config['mpn']) && !empty($data['product_info']['mpn'])) {
                $json['mpn'] = $data['product_info']['mpn'];
                $has_idtentifier = true;
            }

            if (!empty($config['sku'])) {
                $json['sku'] = !empty($data['product_info']['sku']) ? $data['product_info']['sku'] : $data['model'];
            }

            if (!empty($config['upc']) && !empty($data['product_info']['upc'])) {
                $json['gtin12'] = $data['product_info']['upc'];
                $json['gtin'] = $data['product_info']['upc'];
                $has_idtentifier = true;
            } else if (!empty($config['ean']) && !empty($data['product_info']['ean'])) {
                $json['gtin'] = $data['product_info']['ean'];
                $json['gtin8'] = $data['product_info']['ean'];
                $has_idtentifier = true;
            } else if (!empty($config['jan']) && !empty($data['product_info']['jan'])) {
                $json['gtin'] = $data['product_info']['jan'];
                $has_idtentifier = true;
            } else if (!empty($config['isbn']) && !empty($data['product_info']['isbn'])) {
                //$json['gtin13'] = $data['product_info']['isbn'];
                $json['gtin'] = $data['product_info']['isbn'];
                $json['isbn'] = $data['product_info']['isbn'];
                $has_idtentifier = true;
            }

            //if (!empty($config['desc'])) {}
            $json['description'] = strip_tags($data['product_info']['meta_description']);

            if (!empty($config['brand'])) {
                $json['manufacturer'] = strip_tags($data['product_info']['manufacturer']);
                $json['brand'] = array(
                    '@type' => 'Brand',
                    'name' => strip_tags($data['product_info']['manufacturer']),
                );
            }

            if ($data['special']) {
                $specialQuery = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = " . (int)$data['product_id'] . " AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1")->row;

                $json['offers'] = array(
                    '@type' => "Offer",
                    'url' => $product_url,
                    'price' => (string)$data['special'],
                    'priceCurrency' => $data['currency'],
                    'itemCondition' => 'https://schema.org/NewCondition',
                    'seller' => array(
                        '@type' => 'Organization',
                        'name' => $data['config_name'],
                    ),
                );

                if (isset($specialQuery['date_end']) && $specialQuery['date_end'] != '0000-00-00') {
                    $json['offers']['priceValidUntil'] = $specialQuery['date_end'];
                } else {
                    $json['offers']['priceValidUntil'] = date('Y-m-d', strtotime('+1 years', strtotime(date("Y-m-d "))));
                }
            } else {
                $json['offers'] = array(
                    '@type' => "Offer",
                    'url' => $product_url,
                    'price' => (string)$data['price'],
                    'priceCurrency' => $data['currency'],
                    'priceValidUntil' => date('Y-m-d', strtotime('+1 years', strtotime(date("Y-m-d ")))),
                    'itemCondition' => 'https://schema.org/NewCondition',
                    'seller' => array(
                        '@type' => 'Organization',
                        'name' => $data['config_name'],
                    ),
                );
            }

            if ($data['product_info']['quantity'] > 0) {
                $json['offers']['availability'] = 'https://schema.org/InStock';
            } else {
                $stockStatusQuery = $this->db->query("SELECT stock_status_id FROM " . DB_PREFIX . "product WHERE product_id = " . (int)$data['product_id'])->row;

                if (!empty($config['order_status'][$stockStatusQuery['stock_status_id']])) {
                    $json['offers']['availability'] = $config['order_status'][$stockStatusQuery['stock_status_id']];
                }
            }

            if (!empty($config['reviews']) && count($data['reviews'])) {
                $best_rating = 0;

                // get all reviews
                $data['reviews'] = $this->model_catalog_review->getReviewsByProductId($data['product_id'], 0, 999999999999);
                $date_added_months = rand(2,7);
                foreach ($data['reviews'] as $review) {
                    $json['review'][] = array(
                        '@type' => 'Review',
                        'author' => array(
                            '@type' => 'Person',
                            'name' => $review['author'],
                        ),
                        'reviewBody' => $review['text'],
                        'datePublished' => (!empty($review['date_added']) && strtotime($review['date_added']) !== false)
                            ? date('Y-m-d', strtotime($review['date_added']))
                            : date('Y-m-d', strtotime('-'.$date_added_months.' months')),
                        'reviewRating' => array(
                            '@type' => 'Rating',
                            'ratingValue' => $review['rating'],
                            'bestRating' => 5,
                            'worstRating' => 1
                        ),
                    );
                    $best_rating = ($review['rating'] > $best_rating) ? $review['rating'] : 0;
                }
            }else{
                $json['aggregateRating'] = array(
                    '@type' => 'AggregateRating',
                    'ratingValue' => 4.3,
                    'bestRating' => 5,
                    'worstRating' => 1,
                    'reviewCount' => 1
                );
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Organization
        if (in_array($page, array('home', 'contact')) && !empty($config['organization'])) {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'Organization';
            $json['url'] = $data['url'];
            $json['logo'] = $data['logo'];

            if (!empty($config['organization_search'])) {
                $json['potentialAction'][] = array(
                    '@type' => 'SearchAction',
                    'target' => urldecode($this->url->link('product/search', 'search={search_term_string}')),
                    'query-input' => 'required name=search_term_string',
                );
            }

            if (!empty($config['contact'])) {
                foreach ($config['contact'] as $contact) {
                    if (empty($contact['phone'])) continue;

                    $json['contactPoint'][] = array(
                        '@type' => 'ContactPoint',
                        'telephone' => $contact['phone'],
                        'contactType' => $contact['type'],
                    );
                }
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Store
        if (in_array($page, array('home', 'contact')) && !empty($config['store'])) {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'Store';
            $json['url'] = $data['url'];
            $json['name'] = $data['config_name'];
            $json['image'] = $data['logo'];

            if (!empty($config['store_logo'])) {
                $json['logo'] = $data['logo'];
            }

            if (!empty($config['store_mail'])) {
                $json['email'] = $this->config->get('config_email');
            }

            if (!empty($config['store_phone'])) {
                $json['telephone'] = $this->config->get('config_telephone');
            }

            if (!empty($config['address'])) {
                if (!empty($config['address_street'])) $json['address']['streetAddress'] = $config['address_street'];
                if (!empty($config['address_city'])) $json['address']['addressLocality'] = $config['address_city'];
                if (!empty($config['address_region'])) $json['address']['addressRegion'] = $config['address_region'];
                if (!empty($config['address_code'])) $json['address']['postalCode'] = $config['address_code'];
                if (!empty($config['address_country'])) $json['address']['addressCountry'] = $config['address_country'];
            }

            foreach ($config['same_as'] as $same_as) {
                if (empty($same_as)) continue;

                $json['sameAs'][] = $same_as;
            }

            if (!empty($config['pricerange'])) {
                $json['priceRange'][] = $config['pricerange'];
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Website
        if (in_array($page, array('home', 'contact')) && !empty($config['website'])) {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'WebSite';
            $json['url'] = $data['url'];

            if (!empty($config['website_search'])) {
                $json['potentialAction'][] = array(
                    '@type' => 'SearchAction',
                    'target' => urldecode($this->url->link('product/search', 'search={search_term_string}')),
                    'query-input' => 'required name=search_term_string',
                );
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Place
        if (in_array($page, array('home', 'contact')) && !empty($config['place'])) {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'Place';
            $json['name'] = $data['config_name'];

            if (!empty($config['gps_lat']) && !empty($config['gps_long'])) {
                $json['geo'] = array(
                    '@type' => 'GeoCoordinates',
                    'latitude' => $config['gps_lat'],
                    'longitude' => $config['gps_long'],
                );
            }

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        // Blogs
        if ($page == 'blogs') {
            $json = array();
            $json['@context'] = 'http://schema.org';
            $json['@type'] = 'BlogPosting';
            $json['mainEntityOfPage']["@type"] = 'WebPage';
            $json['mainEntityOfPage']["@id"] = $this->url->link('extension/d_blog_module/post', 'post_id=' . $data['post_id'], 'SSL');
            $json['headline'] = $data['title'];
            $json['alternativeHeadline'] = $data['meta_title'];
            $json['image'] = $data['image'];
            $json['author']["@type"] = 'Person';
            $json['author']["name"] = "LovelyPetPal";
            $json['publisher']["@type"] = 'Organization';
            $json['publisher']["name"] = 'LovelyPetPal Shop';
            $json['publisher']["logo"]["@type"] = 'ImageObject';
            $json['publisher']["logo"]["url"] = '/image/catalog/lovelypetpal-logo2.png';
            $json['datePublished'] = $data['date_published'];
            $json['dateModified'] = $data['date_modified'];
            $json['description'] = $data['meta_description'];
            $json['keywords'] = $data['meta_keyword'];
            $json['articleSection'] = 'LovelyPetPal Blogs';
            $json['interactionStatistic']['@type'] = 'InteractionCounter';
            $json['interactionStatistic']['interactionType'] = array('@type' => 'http://schema.org/ViewAction');
            $json['interactionStatistic']['userInteractionCount'] = $data['viewed'];

            $output .= '<script type="application/ld+json">'.json_encode($json).'</script>'."\n";
        }

        if ($output) {
            $output = "<!-- Microdata -->\n".$output."\n";
        }

        return $output;
    }

    public function getAuthorName() {
        $names = [
            "Emma Müller", "Oliver Schmidt", "Sofia Rossi", "Lucas Dupont", "Hannah Novak",
            "Liam Svensson", "Mia Kowalska", "Noah Martins", "Lara Moreau", "Ethan Jensen",
            "Isabella Fernández", "Leo Andersen", "Amelia Marino", "Oscar Fischer", "Chloe Rossi",
            "Alexander Petrov", "Elena Dimitrova", "Maximilian Wagner", "Ava Kovács", "Felix Oliveira"
        ];
        return $names[array_rand($names)];
    }

    // 获取随机评价内容和日期
    public function getAuthorReview() {
        $reviews = [
            "Great quality and super breathable during matches.t.",
            "Fits true to size — love the athletic cut.",
            "The design is bold and exactly what I wanted.",
            "Material feels strong yet lightweight.",
            "Delivered faster than I expected!",
            "Colors are vibrant and don’t fade after washing.",
            "Wore it to practice — super comfy and cool.",
            "Better quality than most jerseys I’ve owned.",
            "The stitching feels solid and well made.",
            "Love how it moves with my body during play.",
            "Got it for a friend and he was thrilled!",
            "No irritation or tight spots — just right.",
            "Great fit in the shoulders and chest.",
            "Customer service answered all my questions.",
            "Feels professional — just like the team’s kit.",
            "Surprisingly soft on the inside.",
            "Very breathable fabric — good for hot days.",
            "Matches perfectly with my team shorts.",
            "Looks exactly like the product photos.",
            "Love the classic style with a modern twist.",
            "Holds up well in the wash — no shrinkage.",
            "The print/logo quality is excellent.",
            "Great jersey for training or casual wear.",
            "Not too tight, not too loose — just right.",
            "Makes me feel part of the team.",
            "Classic design, top‑quality, and incredibly comfortable — 10/10.",
            "Great shirt, vibrant color, and sturdy stitching.",
            "Amazing service, fast delivery, and nice pricing.",
            "Received mine the next day — outstanding speed.",
            "Really good quality and fast delivery — impressed!",
            "Comfortable fit, feels durable in every way.",
            "Sleek design, exactly as pictured online.",
            "Great color retention — no fade after washes.",
            "Feels like authentic pro‑grade gear.",
            "Superb fabric, breathes well during play.",
            "Perfect athletic fit without feeling tight.",
            "Logo and print quality are crisp and sharp.",
            "I got compliments from teammates immediately.",
            "Fantastic value for the price.",
            "Was a bit big, exchanged it — great customer service.",
            "Received a replacement quickly for damaged item — excellent support.",
            "No irritation from seams — very comfortable.",
            "Feels professional and ready for match day.",
            "Great stitching, definitely built to last.",
            "Held up well during intense training sessions.",
            "Lightweight but tough — perfect combo.",
            "Unmatched comfort — couldn’t be happier.",
            "Would definitely recommend to other fans.",
            "Bought a second one — love it that much.",
            "Packs well — ideal for travel.",
            "Feels soft inside despite a rugged exterior.",
            "Great for hot weather — breathable cotton blend.",
            "The collar maintains shape after washes.",
            "Looks sharp on the field and off.",
            "Delivered in perfect condition.",
            "My son absolutely loves his new jersey.",
            "Crisp colors, great for team photo ops.",
            "Makes me feel part of the team spirit.",
            "Excellent match to official team colours.",
            "Feels lightweight and flexible during play.",
            "My go‑to jersey for weekend matches.",
            "Breathability is outstanding on warm days.",
            "Looks pro‑level, performance‑ready.",
            "Ordered for a friend, they loved it too.",
            "Great gift idea for any rugby fan.",
            "Solid quality — no wear after months of use.",
            "The fit is just right — not too snug.",
            "Washes well without shrinking.",
            "Love the contrast striping and styling.",
            "Performance material wicks sweat effectively.",
            "Turns heads at the pub and the pitch.",
            "Great balance of price and quality.",
            "Has that authentic rugby gear feel.",
            "Super happy with this purchase.",
            "I’ll definitely buy more from this brand."
        ];

        $review = $reviews[array_rand($reviews)];
        $date = date('Y-m-d', strtotime('-' . rand(1, 365) . ' days'));

        return ['text' => $review, 'date' => $date];
    }

    public function checkCanonical() {
        if (!$this->config->get('mlseo_canonical')) {
            return;
        }

        foreach ($this->document->getLinks() as $link) {
            if ($link['rel'] == 'canonical') {
                return;
            }
        }

        /*/ no canonical for search page
        if (!empty($this->request->get['route']) && $this->request->get['route'] == 'product/search') {
          return;
        } */

        if (isset($this->request->get['route']) && $this->request->get['route'] != 'common/home') {
            list($ctrl) = explode('/', $this->request->get['route']);

            if (in_array($ctrl, array('account', 'information', 'affiliate', 'checkout'))) {
                $data = $this->request->get;


                $route = $data['route'];
                $params = '';

                unset($data['_route_'], $data['route']);

                if ($data) {
                    $params = urldecode(http_build_query($data, '', '&'));
                }

                $this->document->addLink($this->url->link($route, $params), 'canonical');
            }
        } else {
            $this->document->addLink($this->url->link('common/home'), 'canonical');
        }
    }

    public function addUrl404($url) {
        $url = strip_tags($url); // prevent xss

        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_404 WHERE query = '" . $this->db->escape($url) . "'")->row;

        $referer = !empty($_SERVER['HTTP_REFERER']) ? preg_replace('/^www\./', '', parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) : '';
        $agent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';

        if (!empty($agent)) {
            if (strpos($agent, 'Googlebot') !== false) {
                $agent = 'Google';
            } else if (strpos($agent, 'PetalBot') !== false) {
                $agent = 'PetalSearch';
            } else if (strpos($agent, 'Applebot') !== false) {
                $agent = 'Apple';
            } else if (strpos($agent, 'Yeti') !== false) {
                $agent = 'Yeti';
            } else if (strpos($agent, 'coccocbot') !== false) {
                $agent = 'CocCoc';
            } else if (strpos($agent, 'Bingbot') !== false) {
                $agent = 'Bing';
            } else if (strpos($agent, 'Slurp') !== false) {
                $agent = 'Yahoo';
            } else if (strpos($agent, 'DuckDuckBot') !== false) {
                $agent = 'DuckDuckGo';
            } else if (strpos($agent, 'Baiduspider') !== false) {
                $agent = 'Baidu';
            } else if (strpos($agent, 'YandexBot') !== false) {
                $agent = 'Yandex';
            } else if (strpos($agent, 'Sogou') !== false) {
                $agent = 'Sogou';
            } else if (strpos($agent, 'Exabot') !== false) {
                $agent = 'Exalead';
            } else if (strpos($agent, 'facebot') !== false) {
                $agent = 'Facebook';
            } else if (strpos($agent, 'ia_archiver') !== false) {
                $agent = 'Alexa';
            } else if (strpos($agent, 'SeznamBot') !== false) {
                $agent = 'Seznam';
            } else {
                $agent = '';
            }
        }

        if (!empty($agent)) {
            $referer = 'Bot:'.$agent;
        }

        if (isset($query['count'])) {
            if (empty($query['referer'])) {
                $query['referer'] = $referer;
            } else if ($referer && !empty($query['referer'])) {
                if (strpos($query['referer'], $referer) === false) {
                    $query['referer'] = $query['referer'] . ', ' . $referer;
                }
            }

            $this->db->query("UPDATE " . DB_PREFIX . "url_404 SET count = '".($query['count']+1)."', referer = '". $this->db->escape($query['referer']) . "', date_accessed = NOW() WHERE url_404_id = '". $query['url_404_id'] . "'");
        } else {
            $this->db->query("INSERT INTO " . DB_PREFIX . "url_404 SET query = '". $this->db->escape($url) . "', referer = '". $this->db->escape($referer) . "', count = 1");
        }
    }

    public function ggAnalytics() {
        $ggScript = '';

        $seo_meta = $this->config->get('mlseo_store');
        /*
        if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
          $this->document->addScript('index.php?route=geekodev/analytics', 'footer');
          //$ggScript .= '<script src="'.$this->url->link('geekodev/analytics').'" type="text/javascript"></script>'."\n";
        }
        */
        if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['analytics'])) {
            $ggAnalyticsCode = html_entity_decode($seo_meta[$this->config->get('config_store_id')]['analytics'], ENT_QUOTES, 'UTF-8');

            // Google Analytics 4
            if (substr($ggAnalyticsCode, 0, 2) == 'G-') {
                if (true) {
                    $debug = ",{'debug_mode':true}";
                } else {
                    $debug = '';
                }

                $ggScript .= "<script async src=\"https://www.googletagmanager.com/gtag/js?id=".$ggAnalyticsCode."\"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', '".$ggAnalyticsCode."'".$debug.");
</script>
";

                // Google Analytics 3
            } else {
                $ggScript .= '<script async src="https://www.googletagmanager.com/gtag/js?id='.$ggAnalyticsCode.'"></script>'."\n";
                $ggScript .= "<script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '".$ggAnalyticsCode."');</script>\n";
            }
        }

        if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_adwords']) && !empty($seo_meta[$this->config->get('config_store_id')]['adwords'])) {
            $ggAdwordsCode = $seo_meta[$this->config->get('config_store_id')]['adwords'];

            $ggScript .= '<script async src="https://www.googletagmanager.com/gtag/js?id='.$ggAdwordsCode.'"></script>'."\n";
            $ggScript .= "<script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '".$ggAdwordsCode."');</script>\n";
        }

        if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['analytics'])) {
            $ggAnalyticsCode = html_entity_decode($seo_meta[$this->config->get('config_store_id')]['analytics'], ENT_QUOTES, 'UTF-8');

            // Google Analytics 4
            if (substr($ggAnalyticsCode, 0, 2) == 'G-') {
                // transaction complete
                if (isset($this->request->get['route']) && in_array($this->request->get['route'], array('checkout/success'))) {
                    if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
                        if (isset($this->session->data['ggAnalytics_order_id'])) {
                            $order_id = $this->session->data['ggAnalytics_order_id'];
                            unset($this->session->data['ggAnalytics_order_id']);

                            $trackData = $this->getTrackData(array('action' => 'purchase', 'order_id' => $order_id));

                            $ggScript .= "  <script>gtag('event', 'purchase', ".json_encode($trackData).");</script>\n";
                        }
                    }
                } else if (isset($this->request->get['route']) && in_array($this->request->get['route'], array('product/product')) && !empty($this->request->get['product_id'])) {
                    if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
                        $trackData = $this->getTrackData(array('action' => 'item_view', 'product_id' => $this->request->get['product_id']));

                        $ggScript .= "  <script>gtag('event', 'item_view', ".json_encode($trackData).");</script>\n";
                    }
                }

                // Google Analytics 3
            } else {
                $ggScript .= "<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '".$ggAnalyticsCode."', 'auto');\n";

                if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
                    $ggScript .= "ga('require', 'ec');\n";
                }

                $ggScript .= "ga('send', 'pageview');\n";

                if (isset($this->request->get['route']) && in_array($this->request->get['route'], array('checkout/checkout'))) {
                    //$ggScript .= "gkdEctTrackCheckout(1, 'Enter checkout');\n";
                }

                if (isset($this->request->get['route']) && in_array($this->request->get['route'], array('account/login', 'account/register', 'checkout/cart', 'checkout/checkout'))) {
                    list($cat, $action) = explode('/', $this->request->get['route']);
                    $ggScript .= "ga('send', 'event', '".ucfirst($cat)."', '".ucfirst($action)."');\n";
                }

                // transaction complete
                if (isset($this->request->get['route']) && in_array($this->request->get['route'], array('checkout/success'))) {
                    if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
                        if (isset($this->session->data['ggAnalytics_order_id'])) {
                            $order_id = $this->session->data['ggAnalytics_order_id'];
                            unset($this->session->data['ggAnalytics_order_id']);

                            $this->load->model('checkout/order');
                            $this->load->model('account/order');

                            $order_info = $this->model_checkout_order->getOrder($order_id);

                            if ($order_info) {
                                $subTotal = $tax = $shipping = 0;
                                $coupon = '';

                                foreach ($this->model_account_order->getOrderTotals($order_id) as $order_total) {
                                    if ($order_total['code'] == 'tax') {
                                        $tax += $order_total['value'];
                                    } elseif($order_total['code'] == 'shipping') {
                                        $shipping += $order_total['value'];
                                    } elseif($order_total['code'] == 'sub_total') {
                                        $subTotal += $order_total['value'];
                                    } elseif($order_total['code'] == 'coupon') {
                                        $coupon = $order_total['title'];
                                    }
                                }

                                // calculate total and prices
                                if (1 || !empty($seo_meta[$this->config->get('config_store_id')]['gg_tax'])) {
                                    $total = $order_info['total'];
                                } else {
                                    $total = $subTotal;
                                }

                                if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_currency'])) {
                                    $total = $this->currency->convert($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
                                    $tax = $this->currency->convert($this->currency->format($tax, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
                                    $shipping = $this->currency->convert($this->currency->format($shipping, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
                                } else {
                                    $total = $this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false);
                                    $tax = $this->currency->format($tax, $order_info['currency_code'], $order_info['currency_value'], false);
                                    $shipping = $this->currency->format($shipping, $order_info['currency_code'], $order_info['currency_value'], false);
                                }

                                $total = round($total, 2);
                                $tax = round($tax, 2);

                                $purchase = array(
                                    'id' => $order_info['order_id'],
                                    'revenue' => $total,
                                    'tax' => $tax,
                                    'shipping' => $shipping,
                                    'coupon' => $coupon,
                                );

                                if (!empty($order_info['affiliate_id'])) {
                                    $affiliate_id = $order_info['affiliate_id'];

                                    if (version_compare(VERSION, '3', '>=')) {
                                        $this->load->model('account/customer');
                                        $affiliate_info = $this->model_account_customer->getAffiliate($affiliate_id);
                                    } else {
                                        $this->load->model('affiliate/affiliate');
                                        $affiliate_info = $this->model_affiliate_affiliate->getAffiliate($affiliate_id);
                                    }

                                    $purchase['affiliation'] = $affiliate_info['code'];
                                }

                                $ggScript .= "ga('ec:setAction', 'purchase'," . json_encode($purchase) . ");\n";

                                // set track products
                                $trackProducts = $this->getTrackData(array('order_id' => $order_id));

                                foreach($trackProducts as $prod) {
                                    $ggScript .= "ga('ec:addProduct', " . json_encode($prod) . ");\n";
                                }
                            }
                        }
                    }
                }

                $ggScript .= "if (window.performance) {
    var timeSincePageLoad = Math.round(performance.now());
    ga('send', 'timing', 'Page Load Time', 'load', timeSincePageLoad);
  }";

                $ggScript .= "</script>";
            }
        }

        if (!empty($ggScript)) {
            $this->document->addSeoMeta("\n<!-- gkdAnalytics -->\n".$ggScript."\n\n");
        }

        if (!$this->config->get('mlseo_hreflang')) {
            return;
        }

        if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_analytics']) && !empty($seo_meta[$this->config->get('config_store_id')]['gg_enhanced'])) {
        }
    }

    public function getTrackData($data = array()) {
        $json = array();

        $json['currency'] = $this->session->data['currency'];

        if (!empty($this->request->post['action'])) {
            $action = $this->request->post['action'];
        } else if (!empty($data['action'])) {
            $action = $data['action'];
        } else {
            $action = 'default';
        }

        $order_products_qty = array();

        if (!empty($this->request->post['cart'])) {
            $this->request->post['pid'] = array();

            foreach($this->cart->getProducts() as $prod) {
                $this->request->post['pid'][] = $prod['product_id'];
            }
        } else if (!empty($data['order_id'])) {
            $this->request->post['pid'] = array();

            $this->load->model('checkout/order');
            $this->load->model('account/order');

            $order_info = $this->model_checkout_order->getOrder($data['order_id']);
            $order_products = $this->model_account_order->getOrderProducts($data['order_id']);
            foreach($order_products as $prod) {
                $order_products_qty[$prod['product_id']] = $prod['quantity'];
                $this->request->post['pid'][] = $prod['product_id'];
            }
        } else if (!empty($data['product_id'])) {
            $this->request->post['pid'] = array($data['product_id']);
        }

        // purchase data
        if ($action == 'purchase' && !empty($order_info)) {
            $subTotal = $tax = $shipping = 0;
            $coupon = '';

            foreach ($this->model_account_order->getOrderTotals($order_info['order_id']) as $order_total) {
                if ($order_total['code'] == 'tax') {
                    $tax += $order_total['value'];
                } elseif($order_total['code'] == 'shipping') {
                    $shipping += $order_total['value'];
                } elseif($order_total['code'] == 'sub_total') {
                    $subTotal += $order_total['value'];
                } elseif($order_total['code'] == 'coupon') {
                    $coupon = $order_total['title'];
                }
            }

            // calculate total and prices
            if (1 || !empty($seo_meta[$this->config->get('config_store_id')]['gg_tax'])) {
                $total = $order_info['total'];
            } else {
                $total = $subTotal;
            }

            if (!empty($seo_meta[$this->config->get('config_store_id')]['gg_currency'])) {
                $total = $this->currency->convert($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
                $tax = $this->currency->convert($this->currency->format($tax, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
                $shipping = $this->currency->convert($this->currency->format($shipping, $order_info['currency_code'], $order_info['currency_value'], false), $order_info['currency_code'], $seo_meta[$this->config->get('config_store_id')]['gg_currency']);
            } else {
                $total = $this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false);
                $tax = $this->currency->format($tax, $order_info['currency_code'], $order_info['currency_value'], false);
                $shipping = $this->currency->format($shipping, $order_info['currency_code'], $order_info['currency_value'], false);
            }

            $total = round($total, 2);
            $tax = round($tax, 2);

            $json = array(
                'transaction_id' => $order_info['order_id'],
                'currency' => $order_info['currency_code'],
                'value' => $total,
                'tax' => $tax,
            );

            if (!empty($shipping)) {
                $json['shipping'] = $shipping;
            }

            if (!empty($coupon)) {
                $json['coupon'] = $coupon;
            }

            if (!empty($order_info['affiliate_id'])) {
                $affiliate_id = $order_info['affiliate_id'];

                if (version_compare(VERSION, '3', '>=')) {
                    $this->load->model('account/customer');
                    $affiliate_info = $this->model_account_customer->getAffiliate($affiliate_id);
                } else {
                    $this->load->model('affiliate/affiliate');
                    $affiliate_info = $this->model_affiliate_affiliate->getAffiliate($affiliate_id);
                }

                $purchase['affiliation'] = $affiliate_info['code'];
            }
        }

        // items
        if (!empty($this->request->post['pid'])) {
            $this->load->model('catalog/product');
            $this->load->model('catalog/category');
            $this->load->model('tool/path_manager');

            foreach ((array) $this->request->post['pid'] as $product_id) {
                if (version_compare(VERSION, '3', '>=') && $action == 'remove') {
                    $cart_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "' AND cart_id = '" . (int)$product_id . "'")->row;

                    if (isset($cart_query['product_id'])) {
                        $product_id = $cart_query['product_id'];
                    }
                }

                $product_info = $this->model_catalog_product->getProduct($product_id);

                if ($product_info) {
                    if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
                        $data['price'] = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    } else {
                        $data['price'] = false;
                    }

                    if ((float)$product_info['special']) {
                        $data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    } else {
                        $data['special'] = false;
                    }

                    $path = $this->model_tool_path_manager->getOneProductPath($product_info['product_id']);

                    $productPath = '';

                    if (!empty($path)) {
                        foreach(explode('_', $path) as $catId) {
                            $category_info = $this->model_catalog_category->getCategory($catId);

                            if ($category_info) {
                                $productPath .= ($productPath ? '/' : '') . $category_info['name'];
                            }
                        }
                    }

                    $prodData = array(
                        'item_id' => $product_info['product_id'],
                        'item_name' => $product_info['name'],
                        'quantity' => ( !empty($order_products_qty) && !empty($order_products_qty[$product_info['product_id']]) ) ? $order_products_qty[$product_info['product_id']] : 1,
                    );

                    if ($productPath) {
                        $prodData['item_category'] = $productPath;
                    }

                    if ($product_info['manufacturer']) {
                        $prodData['item_brand'] = $product_info['manufacturer'];
                    }

                    if ($data['price']) {
                        $prodData['price'] = $data['price'];
                    }

                    if (!empty($total) && !isset($json['value'])) {
                        $json['value'] = $total;
                    }

                    $json['items'][] = $prodData;
                }
            }
        }

        return $json;
        // header('Content-Type: application/json');
        // echo json_encode($json);
    }
}
